#pragma once

#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include "Conf.hpp"
#include "Log.hpp"
#include "Err.hpp"

static const int defaultepfd = -1;

class Epoller {
public:
    Epoller() : epfd_(defaultepfd) {}
    void Create(){
        epfd_ = epoll_create(Config::GetInstance()->GetGsize());
        if (epfd_ < 0) {
            Logger::getInstance().loggger()->fatal("epoll_create error, code: %d, errstring: %s", errno, strerror(errno));
            exit(EPOLL_CREAT_ERR);
        }
    }
    // 用户 -> 内核
    bool AddEvent(int fd, uint32_t events) {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;
        int n = epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev);
        if(n < 0) {
            Logger::getInstance().loggger()->fatal("epoll_ctl error, code: %d, errstring: %s", errno, strerror(errno));
            return false;
        }
        return true;
    }
    bool DelEvent(int fd) {
        // epoll在操作fd的时候，有一个要求，fd必须合法！
        return epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, nullptr) == 0;
    }
    bool ModEvent(int fd) {
        struct epoll_event event;
        event.data.fd = fd;
        event.events =  EPOLLOUT;  // 添加对 EPOLLOUT 事件的关注
        return epoll_ctl(epfd_, EPOLL_CTL_MOD, fd, &event) == 0;
    }
    int Wait(struct epoll_event *revs, int num, int timeout) {
        return epoll_wait(epfd_, revs, num, timeout);
    }
    int Fd() {
        return epfd_;
    }
    void Close() {
        if(epfd_ != defaultepfd) close(epfd_); 
    }
    ~Epoller() {}

private:
    int epfd_;
};